package net.minecraft.src;

import java.util.ArrayList;
import java.util.List;
import net.minecraft.src.MovingObjectPosition;
import net.minecraft.src.Vec3D;

public class AxisAlignedBB {

   private static List boundingBoxes = new ArrayList();
   private static int numBoundingBoxesInUse = 0;
   public double minX;
   public double minY;
   public double minZ;
   public double maxX;
   public double maxY;
   public double maxZ;


   public static AxisAlignedBB getBoundingBox(double var0, double var2, double var4, double var6, double var8, double var10) {
      return new AxisAlignedBB(var0, var2, var4, var6, var8, var10);
   }

   public static void func_28196_a() {
      boundingBoxes.clear();
      numBoundingBoxesInUse = 0;
   }

   public static void clearBoundingBoxPool() {
      numBoundingBoxesInUse = 0;
   }

   public static AxisAlignedBB getBoundingBoxFromPool(double var0, double var2, double var4, double var6, double var8, double var10) {
      if(numBoundingBoxesInUse >= boundingBoxes.size()) {
         boundingBoxes.add(getBoundingBox(0.0D, 0.0D, 0.0D, 0.0D, 0.0D, 0.0D));
      }

      return ((AxisAlignedBB)boundingBoxes.get(numBoundingBoxesInUse++)).setBounds(var0, var2, var4, var6, var8, var10);
   }

   private AxisAlignedBB(double var1, double var3, double var5, double var7, double var9, double var11) {
      super();
      this.minX = var1;
      this.minY = var3;
      this.minZ = var5;
      this.maxX = var7;
      this.maxY = var9;
      this.maxZ = var11;
   }

   public AxisAlignedBB setBounds(double var1, double var3, double var5, double var7, double var9, double var11) {
      this.minX = var1;
      this.minY = var3;
      this.minZ = var5;
      this.maxX = var7;
      this.maxY = var9;
      this.maxZ = var11;
      return this;
   }

   public AxisAlignedBB addCoord(double var1, double var3, double var5) {
      double var7 = this.minX;
      double var9 = this.minY;
      double var11 = this.minZ;
      double var13 = this.maxX;
      double var15 = this.maxY;
      double var17 = this.maxZ;
      if(var1 < 0.0D) {
         var7 += var1;
      }

      if(var1 > 0.0D) {
         var13 += var1;
      }

      if(var3 < 0.0D) {
         var9 += var3;
      }

      if(var3 > 0.0D) {
         var15 += var3;
      }

      if(var5 < 0.0D) {
         var11 += var5;
      }

      if(var5 > 0.0D) {
         var17 += var5;
      }

      return getBoundingBoxFromPool(var7, var9, var11, var13, var15, var17);
   }

   public AxisAlignedBB expand(double var1, double var3, double var5) {
      double var7 = this.minX - var1;
      double var9 = this.minY - var3;
      double var11 = this.minZ - var5;
      double var13 = this.maxX + var1;
      double var15 = this.maxY + var3;
      double var17 = this.maxZ + var5;
      return getBoundingBoxFromPool(var7, var9, var11, var13, var15, var17);
   }

   public AxisAlignedBB getOffsetBoundingBox(double var1, double var3, double var5) {
      return getBoundingBoxFromPool(this.minX + var1, this.minY + var3, this.minZ + var5, this.maxX + var1, this.maxY + var3, this.maxZ + var5);
   }

   public double calculateXOffset(AxisAlignedBB var1, double var2) {
      if(var1.maxY > this.minY && var1.minY < this.maxY) {
         if(var1.maxZ > this.minZ && var1.minZ < this.maxZ) {
            double var4;
            if(var2 > 0.0D && var1.maxX <= this.minX) {
               var4 = this.minX - var1.maxX;
               if(var4 < var2) {
                  var2 = var4;
               }
            }

            if(var2 < 0.0D && var1.minX >= this.maxX) {
               var4 = this.maxX - var1.minX;
               if(var4 > var2) {
                  var2 = var4;
               }
            }

            return var2;
         } else {
            return var2;
         }
      } else {
         return var2;
      }
   }

   public double calculateYOffset(AxisAlignedBB var1, double var2) {
      if(var1.maxX > this.minX && var1.minX < this.maxX) {
         if(var1.maxZ > this.minZ && var1.minZ < this.maxZ) {
            double var4;
            if(var2 > 0.0D && var1.maxY <= this.minY) {
               var4 = this.minY - var1.maxY;
               if(var4 < var2) {
                  var2 = var4;
               }
            }

            if(var2 < 0.0D && var1.minY >= this.maxY) {
               var4 = this.maxY - var1.minY;
               if(var4 > var2) {
                  var2 = var4;
               }
            }

            return var2;
         } else {
            return var2;
         }
      } else {
         return var2;
      }
   }

   public double calculateZOffset(AxisAlignedBB var1, double var2) {
      if(var1.maxX > this.minX && var1.minX < this.maxX) {
         if(var1.maxY > this.minY && var1.minY < this.maxY) {
            double var4;
            if(var2 > 0.0D && var1.maxZ <= this.minZ) {
               var4 = this.minZ - var1.maxZ;
               if(var4 < var2) {
                  var2 = var4;
               }
            }

            if(var2 < 0.0D && var1.minZ >= this.maxZ) {
               var4 = this.maxZ - var1.minZ;
               if(var4 > var2) {
                  var2 = var4;
               }
            }

            return var2;
         } else {
            return var2;
         }
      } else {
         return var2;
      }
   }

   public boolean intersectsWith(AxisAlignedBB var1) {
      return var1.maxX > this.minX && var1.minX < this.maxX?(var1.maxY > this.minY && var1.minY < this.maxY?var1.maxZ > this.minZ && var1.minZ < this.maxZ:false):false;
   }

   public AxisAlignedBB offset(double var1, double var3, double var5) {
      this.minX += var1;
      this.minY += var3;
      this.minZ += var5;
      this.maxX += var1;
      this.maxY += var3;
      this.maxZ += var5;
      return this;
   }

   public boolean isVecInside(Vec3D var1) {
      return var1.xCoord > this.minX && var1.xCoord < this.maxX?(var1.yCoord > this.minY && var1.yCoord < this.maxY?var1.zCoord > this.minZ && var1.zCoord < this.maxZ:false):false;
   }

   public double getAverageEdgeLength() {
      double var1 = this.maxX - this.minX;
      double var3 = this.maxY - this.minY;
      double var5 = this.maxZ - this.minZ;
      return (var1 + var3 + var5) / 3.0D;
   }

   public AxisAlignedBB func_28195_e(double var1, double var3, double var5) {
      double var7 = this.minX + var1;
      double var9 = this.minY + var3;
      double var11 = this.minZ + var5;
      double var13 = this.maxX - var1;
      double var15 = this.maxY - var3;
      double var17 = this.maxZ - var5;
      return getBoundingBoxFromPool(var7, var9, var11, var13, var15, var17);
   }

   public AxisAlignedBB copy() {
      return getBoundingBoxFromPool(this.minX, this.minY, this.minZ, this.maxX, this.maxY, this.maxZ);
   }

   public MovingObjectPosition func_1169_a(Vec3D var1, Vec3D var2) {
      Vec3D var3 = var1.getIntermediateWithXValue(var2, this.minX);
      Vec3D var4 = var1.getIntermediateWithXValue(var2, this.maxX);
      Vec3D var5 = var1.getIntermediateWithYValue(var2, this.minY);
      Vec3D var6 = var1.getIntermediateWithYValue(var2, this.maxY);
      Vec3D var7 = var1.getIntermediateWithZValue(var2, this.minZ);
      Vec3D var8 = var1.getIntermediateWithZValue(var2, this.maxZ);
      if(!this.isVecInYZ(var3)) {
         var3 = null;
      }

      if(!this.isVecInYZ(var4)) {
         var4 = null;
      }

      if(!this.isVecInXZ(var5)) {
         var5 = null;
      }

      if(!this.isVecInXZ(var6)) {
         var6 = null;
      }

      if(!this.isVecInXY(var7)) {
         var7 = null;
      }

      if(!this.isVecInXY(var8)) {
         var8 = null;
      }

      Vec3D var9 = null;
      if(var3 != null && (var9 == null || var1.squareDistanceTo(var3) < var1.squareDistanceTo(var9))) {
         var9 = var3;
      }

      if(var4 != null && (var9 == null || var1.squareDistanceTo(var4) < var1.squareDistanceTo(var9))) {
         var9 = var4;
      }

      if(var5 != null && (var9 == null || var1.squareDistanceTo(var5) < var1.squareDistanceTo(var9))) {
         var9 = var5;
      }

      if(var6 != null && (var9 == null || var1.squareDistanceTo(var6) < var1.squareDistanceTo(var9))) {
         var9 = var6;
      }

      if(var7 != null && (var9 == null || var1.squareDistanceTo(var7) < var1.squareDistanceTo(var9))) {
         var9 = var7;
      }

      if(var8 != null && (var9 == null || var1.squareDistanceTo(var8) < var1.squareDistanceTo(var9))) {
         var9 = var8;
      }

      if(var9 == null) {
         return null;
      } else {
         byte var10 = -1;
         if(var9 == var3) {
            var10 = 4;
         }

         if(var9 == var4) {
            var10 = 5;
         }

         if(var9 == var5) {
            var10 = 0;
         }

         if(var9 == var6) {
            var10 = 1;
         }

         if(var9 == var7) {
            var10 = 2;
         }

         if(var9 == var8) {
            var10 = 3;
         }

         return new MovingObjectPosition(0, 0, 0, var10, var9);
      }
   }

   private boolean isVecInYZ(Vec3D var1) {
      return var1 == null?false:var1.yCoord >= this.minY && var1.yCoord <= this.maxY && var1.zCoord >= this.minZ && var1.zCoord <= this.maxZ;
   }

   private boolean isVecInXZ(Vec3D var1) {
      return var1 == null?false:var1.xCoord >= this.minX && var1.xCoord <= this.maxX && var1.zCoord >= this.minZ && var1.zCoord <= this.maxZ;
   }

   private boolean isVecInXY(Vec3D var1) {
      return var1 == null?false:var1.xCoord >= this.minX && var1.xCoord <= this.maxX && var1.yCoord >= this.minY && var1.yCoord <= this.maxY;
   }

   public void setBB(AxisAlignedBB var1) {
      this.minX = var1.minX;
      this.minY = var1.minY;
      this.minZ = var1.minZ;
      this.maxX = var1.maxX;
      this.maxY = var1.maxY;
      this.maxZ = var1.maxZ;
   }

   public String toString() {
      return "box[" + this.minX + ", " + this.minY + ", " + this.minZ + " -> " + this.maxX + ", " + this.maxY + ", " + this.maxZ + "]";
   }

}
